package com.easylinkin.linkappapi.common.utils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import lombok.extern.slf4j.Slf4j;

/**
 * @author zhengwen
 **/
@Slf4j
public class HeaderMapRequestWrapper extends HttpServletRequestWrapper {

  /**
   * construct a wrapper for this request
   *
   * @param request
   */
  public HeaderMapRequestWrapper(HttpServletRequest request) {
    super(request);
  }

  private Map<String, String> headerMap = new HashMap<>();

  /**
   * add a header with given name and value
   *
   * @param name
   * @param value
   */
  public void addHeader(String name, String value) {
    headerMap.put(name, value);
  }

  @Override
  public String getHeader(String name) {
    log.info("getHeader --->{}", name);
    String headerValue = super.getHeader(name);
    if (headerMap.containsKey(name)) {
      headerValue = headerMap.get(name);
    }
    return headerValue;
  }

  /**
   * get the Header names
   */
  @Override
  public Enumeration<String> getHeaderNames() {
    List<String> names = Collections.list(super.getHeaderNames());
    for (String name : headerMap.keySet()) {
      names.add(name);
    }
    return Collections.enumeration(names);
  }

  @Override
  public Enumeration<String> getHeaders(String name) {
    log.info("getHeaders --->>>>>>{}", name);
    List<String> values = Collections.list(super.getHeaders(name));
    log.info("getHeaders --->>>>>>{}", values);
    if (headerMap.containsKey(name)) {
      log.info("getHeaders --->{}", headerMap.get(name));
      values = Arrays.asList(headerMap.get(name));
    }
    return Collections.enumeration(values);
  }

  private Map<String, String[]> params = new HashMap<String, String[]>();

  @SuppressWarnings("unchecked")
  public void ParameterRequestWrapper(HttpServletRequest request) {
    // 将request交给父类，以便于调用对应方法的时候，将其输出，其实父亲类的实现方式和第一种new的方式类似
    //super(request);
    //将参数表，赋予给当前的Map以便于持有request中的参数
    this.params.putAll(request.getParameterMap());
  }

  //重载一个构造方法
  public void ParameterRequestWrapper(HttpServletRequest request,
      Map<String, Object> extendParams) {
    //this(request);
    addAllParameters(extendParams);
  }

  @Override
  public String getParameter(String name) {//重写getParameter，代表参数从当前类中的map获取
    String[] values = params.get(name);
    if (values == null || values.length == 0) {
      return null;
    }
    return values[0];
  }

  public String[] getParameterValues(String name) {//同上
    return params.get(name);
  }

  public void addAllParameters(Map<String, Object> otherParams) {
    //增加多个参数
    for (Map.Entry<String, Object> entry : otherParams.entrySet()) {
      addParameter(entry.getKey(), entry.getValue());
    }
  }


  public void addParameter(String name, Object value) {
    //增加参数
    if (value != null) {
      if (value instanceof ArrayList) {
        String value1 = String.valueOf(value).substring(1, String.valueOf(value).length());
        value = value1.substring(0, value1.length() - 1);
        params.put(name, new String[]{(String) value});
      } else if (value instanceof String[]) {
        params.put(name, (String[]) value);
      } else if (value instanceof String) {
        params.put(name, new String[]{(String) value});
      } else {
        params.put(name, new String[]{String.valueOf(value)});
      }
    }
  }

}
